home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / PROGENV / Reference.C < prev    next >
C/C++ Source or Header  |  1992-04-27  |  4KB  |  258 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "Reference.h"
  6.  
  7. #include "Class.h"
  8. #include "ObjectTable.h"
  9. #include "String.h"
  10. #include "Exception.h"
  11.  
  12. //---- reference ---------------------------------------------------------------
  13.  
  14. NewMetaImpl(Ref, Object, (T(type), T(offset), T(len), TP(cla), TX(base)));
  15.  
  16. Ref::Ref()
  17. {
  18.     base= 0;
  19.     type= offset= 0;
  20.     len= -1;
  21.     cla= 0;
  22. }
  23.  
  24. Ref::Ref(void *b, int t, int o, int l, Class *c, bool g, bool lg)
  25. {
  26.     base= b;
  27.     type= t;
  28.     offset= o;
  29.     len= l;
  30.     cla= c;
  31.     SetFlag(eRefGlobal, g);
  32.     SetFlag(eRefLenGlobal, lg);
  33. }
  34.  
  35. Ref::Ref(Object &op)
  36. {
  37.     base= &op;
  38.     type= offset= 0;
  39.     len= -1;
  40.     cla= op.IsA();
  41. }
  42.  
  43. Ref::Ref(Object *&op)
  44. {
  45.     base= &op;
  46.     type= T_PTR;
  47.     offset= 0;
  48.     len= -1;
  49.     cla= op->IsA();
  50. }
  51.  
  52. Ref::Ref(const Ref &ref)
  53. {
  54.     base= ref.base;
  55.     type= ref.type;
  56.     offset= ref.offset;
  57.     len= ref.len;
  58.     cla= ref.cla;
  59. }
  60.  
  61. void Ref::operator=(Ref ref)
  62. {
  63.     base= ref.base;
  64.     type= ref.type;
  65.     offset= ref.offset;
  66.     len= ref.len;
  67.     cla= ref.cla;
  68. }
  69.  
  70. bool Ref::IsEqual(Object *op)
  71. {
  72.     if (op->IsKindOf(Ref))
  73.     return (((Ref*)op)->base == base) && (((Ref*)op)->offset == offset);
  74.     return FALSE;
  75. }
  76.  
  77. bool Ref::IsObject()
  78. {
  79.     if (type & (T_ARR|T_VEC|T_PTR2))
  80.     return FALSE;
  81.     return cla && cla->TestFlag(eClassObject) && (type == 0)
  82.                     && ObjectTable::PtrIsValid((Object*)base);
  83. }
  84.  
  85. void *Ref::Addr()
  86. {
  87.     if (IsGlobal())
  88.     return (void*) offset;
  89.     return (void*) ((u_long)base + (u_long)offset);
  90. }
  91.  
  92. int Ref::Size()
  93. {
  94.     if (type == 0 && cla)
  95.     return cla->Size();
  96.     return sizeof(void*);
  97. }
  98.  
  99. int Ref::Length()
  100. {
  101.     int l= 0;
  102.  
  103.     if (type & T_ARR)
  104.     return len;
  105.     if (type & T_VEC) {
  106.     int *ll;
  107.     if (TestFlag(eRefLenGlobal))
  108.         ll= (int*) len;
  109.     else
  110.         ll= (int*) ((u_long) base + (u_long) len);
  111.  
  112.     TRY {
  113.         l= *ll;
  114.     } CATCH(ex) {
  115.         return -2;
  116.     } ENDTRY
  117.  
  118.     return l;
  119.     }
  120.     if (type & T_STR) {
  121.     int s;
  122.     if ((type & ~T_STR) == 0 && cla)
  123.         s= cla->Size();
  124.     else
  125.         s= sizeof(void*);
  126.     void *val= (void*) *((u_long*) Addr());
  127.     if (val == 0)
  128.         return -1;
  129.     TRY {
  130.         switch (s) {
  131.         case 1:
  132.         char *cp= (char*)val;
  133.         while (*cp++)
  134.             l++;
  135.         break;
  136.         case 2:
  137.         short *sp= (short*)val;
  138.         while (*sp++)
  139.             l++;
  140.         break;
  141.         case 4:
  142.         int *ip= (int*)val;
  143.         while (*ip++)
  144.             l++;
  145.         break;
  146.         }
  147.     } CATCH(ex) {
  148.         return -2;
  149.     } ENDTRY
  150.     return l;
  151.     }
  152.     return -1;
  153. }
  154.  
  155. Ref *Ref::Deref()
  156. {
  157.     void *oo= 0, *oo2= 0;
  158.     
  159.     if (type == 0) {    // simple
  160.     if (IsObject())
  161.         return new Ref(Addr(), type, 0, Length(), cla);
  162.     return 0;
  163.     }
  164.     
  165.     if (type & T_ARR)   // inline array of simple
  166.     return new Ref(Addr(), type & ~T_ARR, 0, Length(), cla);
  167.  
  168.     TRY {
  169.     oo= (void*) *((int*)Addr());
  170.     } CATCH(ex) {
  171.     return 0;
  172.     } ENDTRY
  173.     
  174.     TRY {
  175.     oo2= (void*) *((int*)oo);
  176.     } CATCH(ex) {
  177.     return 0;
  178.     } ENDTRY
  179.  
  180.     if (oo == 0)
  181.     return 0;
  182.  
  183.     if (type & (T_VEC|T_STR|T_PTR))
  184.     return new Ref(oo, type & ~(T_VEC|T_STR|T_PTR), 0, Length(), cla);
  185.  
  186.     if (type & T_PTR2)
  187.     return new Ref(oo, type & ~T_PTR2, 0, -1, cla);
  188.  
  189.     return 0;   // cannot happen
  190. }
  191.  
  192. char *Ref::Value(char *name)
  193. {
  194.     int l;
  195.     void *val;
  196.     bool isptr= TRUE,
  197.      getvalue= FALSE;
  198.     char *pre= "  ",
  199.      *post,
  200.      buf[400],
  201.      *bp;
  202.     
  203.     if ((type & T_PTR) && (type & T_PTR2))
  204.     pre= "**";
  205.     else if ((type & T_PTR) || (type & T_PTR2))
  206.     pre= " *";
  207.  
  208.     switch (l= Length()) {
  209.     case -2:
  210.     post= "[<ill addr>]";
  211.     break;
  212.     case -1:
  213.     post= "";
  214.     break;
  215.     default:
  216.     post= form("[%d]", l);
  217.     break;
  218.     }
  219.  
  220.     memset(buf, 0, 400);
  221.     bp= buf;
  222.     val= Addr();
  223.     
  224.     if (type & T_ARR) {
  225.     strcpy(bp, "<inline> ");
  226.     bp+= strlen(bp);
  227.     if (! (type & T_PTR2))
  228.         getvalue= TRUE;
  229.     } else if (type == 0) {
  230.     isptr= FALSE;
  231.     getvalue= TRUE;
  232.     } else {
  233.     val= *((void**) val);
  234.     if (val) {
  235.         strcpy(bp, form("0x%08x ", val));
  236.         bp+= strlen(bp);
  237.         if ((type & (T_PTR|T_VEC|T_STR)) && !(type & T_PTR2) || (type == T_PTR2))
  238.         getvalue= TRUE;
  239.     } else
  240.         strcpy(bp, "<nil>");
  241.     }
  242.  
  243.     if (getvalue) {
  244.     TRY {
  245.         cla->Show(bp, val, l, isptr);
  246.     } CATCH(ex) {
  247.         strcat(bp, "<illegal address>");
  248.     } ENDTRY
  249.     }
  250.     
  251.     return form("  %-14.14s %1s%-18.18s: %s",
  252.             cla->Name(),
  253.             pre,
  254.             form("%s%s%s ", IsGlobal() ? "::" : "", name, post),
  255.             buf);
  256. }
  257.  
  258.